class Game {
  constructor() {
    this.board = Array(4).fill().map(() => Array(4).fill(0));
    this.score = 0;
    this.addRandomTile();
    this.addRandomTile();
  }

  addRandomTile() {
    const emptyCells = [];
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (this.board[i][j] === 0) {
          emptyCells.push({i, j});
        }
      }
    }
    
    if (emptyCells.length > 0) {
      const {i, j} = emptyCells[Math.floor(Math.random() * emptyCells.length)];
      this.board[i][j] = Math.random() < 0.9 ? 2 : 4;
    }
  }

  move(direction) {
    let moved = false;
    
    // 转置矩阵以便统一处理
    if (direction === 'up' || direction === 'down') {
      this.board = this.board[0].map((_, colIndex) => 
        this.board.map(row => row[colIndex]));
    }
    
    // 处理移动
    for (let i = 0; i < 4; i++) {
      const row = this.board[i].filter(cell => cell !== 0);
      
      // 合并相同数字
      const start = direction === 'right' || direction === 'down' ? row.length - 1 : 0;
      const end = direction === 'right' || direction === 'down' ? 0 : row.length - 1;
      const step = direction === 'right' || direction === 'down' ? -1 : 1;
      
      for (let j = start; direction === 'right' || direction === 'down' ? j > end : j < end; j += step) {
        if (j + step >= 0 && j + step < row.length && row[j] === row[j + step] && row[j] !== 0) {
          row[j] *= 2;
          this.score += row[j];
          row.splice(j + step, 1);
          moved = true;
        }
      }
      
      // 根据方向填充0
      if (direction === 'right' || direction === 'down') {
        while (row.length < 4) {
          row.unshift(0);
        }
      } else {
        while (row.length < 4) {
          row.push(0);
        }
      }
      
      if (!this.board[i].every((val, index) => val === row[index])) {
        moved = true;
      }
      
      this.board[i] = row;
    }
    
    // 恢复矩阵
    if (direction === 'up' || direction === 'down') {
      this.board = this.board[0].map((_, colIndex) => 
        this.board.map(row => row[colIndex]));
    }
    
    return moved;
  }

  start() {
    this.initDOM();
    this.printBoard();
    this.addRandomTile();
    this.addRandomTile();
    this.printBoard();
  }
  
  initDOM() {
    document.body.innerHTML = `
      <div id="game">
        <h1>2048</h1>
        <div id="score-container">分数: <span id="score">0</span></div>
        <div id="board"></div>
      </div>
    `;
    
    const boardElement = document.getElementById('board');
    boardElement.style.display = 'grid';
    boardElement.style.gridTemplateColumns = 'repeat(4, 100px)';
    boardElement.style.gridTemplateRows = 'repeat(4, 100px)';
    boardElement.style.gap = '10px';
    
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        const cell = document.createElement('div');
        cell.id = `cell-${i}-${j}`;
        cell.style.backgroundColor = '#cdc1b4';
        cell.style.borderRadius = '5px';
        cell.style.display = 'flex';
        cell.style.justifyContent = 'center';
        cell.style.alignItems = 'center';
        cell.style.fontSize = '35px';
        cell.style.fontWeight = 'bold';
        boardElement.appendChild(cell);
      }
    }
    
    // 添加键盘事件
    document.addEventListener('keydown', (e) => {
      let moved = false;
      
      switch (e.key.toLowerCase()) {
        case 'arrowup': case 'w': moved = this.move('up'); break;
        case 'arrowleft': case 'a': moved = this.move('left'); break;
        case 'arrowdown': case 's': moved = this.move('down'); break;
        case 'arrowright': case 'd': moved = this.move('right'); break;
      }
      
      if (moved) {
        this.addRandomTile();
        this.printBoard();
        document.getElementById('score').textContent = this.score;
      }
    });
    
    // 添加触摸事件
    let touchStartX = 0;
    let touchStartY = 0;
    document.addEventListener('touchstart', (e) => {
      e.preventDefault();
      touchStartX = e.touches[0].clientX;
      touchStartY = e.touches[0].clientY;
    }, { passive: false });
    
    document.addEventListener('touchend', (e) => {
      e.preventDefault();
      const touchEndX = e.changedTouches[0].clientX;
      const touchEndY = e.changedTouches[0].clientY;
      const dx = touchEndX - touchStartX;
      const dy = touchEndY - touchStartY;
      
      // 优化滑动判断，增加防抖和灵敏度
      const minDistance = 20;
      if (Math.abs(dx) > minDistance || Math.abs(dy) > minDistance) {
        if (Math.abs(dx) > Math.abs(dy)) {
          if (dx > 0) moved = this.move('right');
          else moved = this.move('left');
        } else {
          if (dy > 0) moved = this.move('down');
          else moved = this.move('up');
        }
      }
      
      if (moved) {
        this.addRandomTile();
        this.printBoard();
        document.getElementById('score').textContent = this.score;
      }
    }, false);
    
  }

  checkGameOver() {
    // 检查是否还有空位
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (this.board[i][j] === 0) return false;
      }
    }
    
    // 检查是否还能合并
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (j < 3 && this.board[i][j] === this.board[i][j + 1]) return false;
        if (i < 3 && this.board[i][j] === this.board[i + 1][j]) return false;
      }
    }
    
    return true;
  }

  printBoard() {
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        const cell = document.getElementById(`cell-${i}-${j}`);
        if (!cell) continue;
        const value = this.board[i][j];
        cell.textContent = value || '';
        cell.style.color = value ? (value < 8 ? '#776e65' : '#f9f6f2') : '#776e65';
        cell.style.backgroundColor = value ? 
          `hsl(${25 - Math.log2(value) * 5}, ${100 - Math.log2(value) * 10}%, ${90 - Math.log2(value) * 3}%)` : 
          '#cdc1b4';
      }
    }
    
    if (this.checkGameOver()) {
      const gameOver = document.createElement('div');
      gameOver.id = 'game-over';
      gameOver.innerHTML = `
        <div style="text-align: center;">
          <div style="font-size: 60px; font-weight: bold; margin-bottom: 20px;">游戏结束！</div>
          <button id="restart" style="padding: 10px 20px; background: #8f7a66; color: white; border: none; border-radius: 5px; font-size: 18px; cursor: pointer;">重新开始</button>
        </div>
      `;
      gameOver.style.position = 'absolute';
      gameOver.style.top = '50%';
      gameOver.style.left = '50%';
      gameOver.style.transform = 'translate(-50%, -50%)';
      gameOver.style.backgroundColor = 'rgba(238, 228, 218, 0.73)';
      gameOver.style.color = '#776e65';
      gameOver.style.padding = '20px 40px';
      gameOver.style.borderRadius = '10px';
      gameOver.style.zIndex = '100';
      document.getElementById('game').appendChild(gameOver);
      
      document.getElementById('restart').addEventListener('click', () => {
        this.board = Array(4).fill().map(() => Array(4).fill(0));
        this.score = 0;
        this.addRandomTile();
        this.addRandomTile();
        this.printBoard();
        document.getElementById('score').textContent = this.score;
        gameOver.remove();
      });
    } else {
      const gameOver = document.getElementById('game-over');
      if (gameOver) gameOver.remove();
    }
  }
}